package com.zxs.seckillservice.customer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.zxs.constant.Constants;
import com.zxs.entity.Orders;
import com.zxs.seckillservice.service.impl.OrderServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.logging.Logger;

/**
 * 消息监听者，接收订单消息
 */
@Component
public class OrderCustomer {

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private OrderServiceImpl orderService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @RabbitListener(queues = {Constants.QUEUE_NAME_ORDER},concurrency = "8")
    public void receiveMessage(Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {
            //读取订单消息
            Orders orders = objectMapper.readValue(message.getBody(), Orders.class);

            //读取订单后下单  调用service层的doOrder方法
            int i = orderService.doOrder(orders);
            if (i == 1) {
                //下单成功
                //向redis中存入订单结果 key: redis:result:+goodsId+:uid value: orders
                //为了防止同一个用户购买两个本商品  秒杀一个商品用户只能买一次
                ValueOperations ops = redisTemplate.opsForValue();
                //Redis中商品库存-1  lua脚本中进行了-1
                /*Integer store = (Integer) ops.get(Constants.REDIS_STORE + orders.getGoodsId());
                ops.set(Constants.REDIS_STORE + orders.getGoodsId(), store - 1);*/
                //向redis中存入订单结果 key: redis:result:+goodsId+:uid value: orders
                ops.set(Constants.REDIS_RESULT + orders.getGoodsId() + ":" + orders.getUid(), orders);

                //向延迟队列中发送一条信息   目的判断支付是否成功
                //向mq发送了延迟消息，把订单的ID发送给了mq
                sendMessage(orders.getId());

                //确认消息  false 表示不批量处理
                channel.basicAck(deliveryTag, false);
                return;
            }
            //不确认消息，重新入队
            channel.basicNack(deliveryTag, false, true);

        } catch (IOException e) {
            e.printStackTrace();

            int count = 0;
            while (count < 3) {
                channel.basicNack(deliveryTag, false, true);
                count++;
            }

            //重新入队三次，还是失败  说明下单失败。直接拒绝消息
            channel.basicReject(deliveryTag, false);
        }
    }


    public void sendMessage(Integer orderId) {
        MessageProperties messageProperties = new MessageProperties();
        //设置消息延迟时间
        messageProperties.setHeader("x-delay", Constants.DELAY_TIME);
        Message message = new Message(orderId.toString().getBytes(), messageProperties);
        //发送消息
        rabbitTemplate.convertAndSend(Constants.EXCHANGE_DELAY_NAME, Constants.ROUTING_KEY_DELAY_NAME, message);
    }

}
